<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>C语言基础 - 字符串处理</title>
    <link rel="stylesheet" href="common.css">
    <style>
        /* 页面特有样式 */
        .string-card {
            background-color: #f5f9ff;
            border-radius: 8px;
            padding: 20px;
            margin-bottom: 25px;
            border-left: 4px solid #5D9CEC;
        }
        
        .definition-box {
            background-color: #f0f7ff;
            padding: 15px;
            border-radius: 5px;
            margin: 15px 0;
        }
        
        .function-box {
            background-color: #fff3e0;
            padding: 15px;
            border-radius: 5px;
            margin: 15px 0;
        }
        
        .io-box {
            background-color: #e8f5e9;
            padding: 15px;
            border-radius: 5px;
            margin: 15px 0;
        }
        
        .warning-note {
            background-color: #ffebee;
            border-left: 4px solid #f44336;
            padding: 12px;
            margin: 15px 0;
        }
        
        .best-practice {
            background-color: #e3f2fd;
            padding: 12px;
            border-left: 4px solid #2196F3;
            margin: 15px 0;
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>C语言基础入门课程</h1>
        </header>
        
        <nav>
            <a href="index.html">首页</a>
            <a href="02-intro.html">C语言简介与环境搭建</a>
            <a href="03-structure.html" class="current">C程序结构</a>
            <a href="04-datatypes.html">基本数据类型</a>
            <a href="05-variables.html">变量与常量</a>
            <a href="06-operators.html">运算符</a>
            <a href="07-io.html" class="current">输入输出</a>
            <a href="08-conditionals.html">条件语句</a>
            <a href="09-loops.html">循环结构</a>
            <a href="10-functions.html" class="current">函数基础</a>
            <a href="11-scope.html">作用域与存储类</a>
            <a href="12-recursion.html">递归函数</a>
            <a href="13-arrays.html">一维数组</a>
            <a href="14-multidim.html" class="current">多维数组</a>
            <a href="15-strings.html">字符串处理</a>
            <a href="16-pointers.html">指针基础</a>
            <a href="17-pointers_advanced.html" class="current">指针进阶</a>
            <a href="18-structs.html">结构体</a>
            <a href="19-files.html">文件操作</a>
            <a href="20-project.html">综合项目</a>
        </nav>
        
        <main>
            <h2>C语言字符串处理</h2>
            
            <section>
                <h3>字符串概述</h3>
                <p>C语言中，字符串是以空字符'\0'结尾的字符数组。</p>
            </section>
            
            <div class="string-card">
                <h3>1. 字符数组与字符串</h3>
                
                <div class="definition-box">
                    <h4>字符数组声明</h4>
                    <pre><code>// 方式1: 固定大小数组
char str1[20];

// 方式2: 初始化时自动确定大小
char str2[] = {'H', 'e', 'l', 'l', 'o', '\0'};

// 方式3: 字符串字面量初始化
char str3[] = "Hello";  // 自动添加'\0'</code></pre>
                </div>
                
                <div class="definition-box">
                    <h4>字符串与字符数组的区别</h4>
                    <ul>
                        <li>字符串必须以'\0'结尾</li>
                        <li>字符数组可以不包含'\0'</li>
                        <li>字符串是字符数组的特例</li>
                    </ul>
                    <pre><code>char arr1[] = {'a', 'b', 'c'};      // 字符数组(不是字符串)
char arr2[] = {'a', 'b', 'c', '\0'}; // 字符串</code></pre>
                </div>
                
                <div class="warning-note">
                    <h4>注意事项</h4>
                    <ul>
                        <li>数组大小应比字符串长度至少大1(存放'\0')</li>
                        <li>字符串字面量不可修改</li>
                        <li>字符数组可以修改</li>
                    </ul>
                </div>
            </div>
            
            <div class="string-card">
                <h3>2. 常用字符串函数</h3>
                <p>使用字符串函数需包含<string.h>头文件</p>
                
                <div class="function-box">
                    <h4>strlen - 字符串长度</h4>
                    <pre><code>size_t strlen(const char *str);
// 返回不包括'\0'的长度

char str[] = "Hello";
int len = strlen(str);  // len = 5</code></pre>
                </div>
                
                <div class="function-box">
                    <h4>strcpy - 字符串复制</h4>
                    <pre><code>char *strcpy(char *dest, const char *src);
// 将src复制到dest(包括'\0')

char src[] = "Hello";
char dest[10];
strcpy(dest, src);  // dest = "Hello"</code></pre>
                </div>
                
                <div class="function-box">
                    <h4>strcat - 字符串连接</h4>
                    <pre><code>char *strcat(char *dest, const char *src);
// 将src追加到dest末尾

char str[20] = "Hello";
strcat(str, " World");  // str = "Hello World"</code></pre>
                </div>
                
                <div class="function-box">
                    <h4>strcmp - 字符串比较</h4>
                    <pre><code>int strcmp(const char *str1, const char *str2);
// 返回0表示相等，负数str1<str2，正数str1>str2

if (strcmp(str1, str2) == 0) {
    printf("字符串相等");
}</code></pre>
                </div>
                
                <div class="best-practice">
                    <h4>安全版本函数(C11)</h4>
                    <p>为防止缓冲区溢出，建议使用带n的函数：</p>
                    <ul>
                        <li>strncpy(dest, src, n)</li>
                        <li>strncat(dest, src, n)</li>
                        <li>strncmp(str1, str2, n)</li>
                    </ul>
                </div>
            </div>
            
            <div class="string-card">
                <h3>3. 字符串输入输出</h3>
                
                <div class="io-box">
                    <h4>printf/scanf</h4>
                    <pre><code>char name[50];
printf("请输入姓名: ");
scanf("%49s", name);  // 限制长度防止溢出
printf("你好，%s!\n", name);</code></pre>
                </div>
                
                <div class="io-box">
                    <h4>gets/fgets (推荐使用fgets)</h4>
                    <pre><code>char line[100];
// 不安全，已弃用
// gets(line);

// 安全方式
fgets(line, sizeof(line), stdin);
// 会保留换行符</code></pre>
                </div>
                
                <div class="io-box">
                    <h4>puts/fputs</h4>
                    <pre><code>char msg[] = "Hello World";
puts(msg);   // 自动添加换行符
fputs(msg, stdout);  // 不添加换行符</code></pre>
                </div>
                
                <div class="warning-note">
                    <h4>常见问题</h4>
                    <ul>
                        <li>scanf读取字符串遇到空格会停止</li>
                        <li>gets不检查缓冲区大小，非常危险</li>
                        <li>fgets会保留输入中的换行符</li>
                        <li>忘记为字符串分配足够空间</li>
                    </ul>
                </div>
            </div>
            
            <section>
                <h3>综合示例</h3>
                <pre><code>#include <stdio.h>
#include <string.h>

int main() {
    // 字符串拼接示例
    char firstName[20] = "张";
    char lastName[20] = "三";
    char fullName[40];
    
    strcpy(fullName, firstName);
    strcat(fullName, lastName);
    printf("姓名: %s\n", fullName);
    
    // 字符串比较示例
    char password[20];
    printf("请输入密码: ");
    fgets(password, sizeof(password), stdin);
    
    // 去除fgets读取的换行符
    password[strcspn(password, "\n")] = '\0';
    
    if (strcmp(password, "123456") == 0) {
        printf("密码正确\n");
    } else {
        printf("密码错误\n");
    }
    
    // 字符串查找示例
    char text[] = "C语言程序设计";
    char *pos = strstr(text, "程序");
    if (pos != NULL) {
        printf("找到子串，位置: %ld\n", pos - text);
    }
    
    return 0;
}</code></pre>
            </section>
        </main>
        
        <footer>
             <p>&copy; </p>
        </footer>
        
        <!-- 二维码区域 -->

    </div> <!-- 结束.container -->
</body>
</html>